package com.yj.netty.chapter01;

import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.util.concurrent.TimeUnit;

/**
 * group()：指定线程模型
 * channel()：指定IO模型
 * attr()：设置属性
 * handler()：给客户端Channel指定处理逻辑Handler
 * option()：给客户端Channel设置底层TCP的属性
 * connect()：连接到远程服务器
 * bind()：绑定本地端口
 * register()：注册到某个事件循环
 * deregister()：注销某个事件循环
 * write()：向客户端发送数据
 * flush()：刷新缓冲区
 * read()：从客户端读取数据
 * close()：关闭客户端Channel
 * closeFuture()：获取关闭Future
 */

public class NettyClient {


    public static void main(String[] args) {

        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(group)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) {
                            ChannelPipeline p = ch.pipeline();
                            p.addLast(new MyClientInitializer()); // 添加自定义handler到ChannelPipeline
                        }
                    });

            ChannelFuture future = bootstrap.connect("127.0.0.1", 8080).sync();
            //future.channel().closeFuture().sync();

            // 监听连接状态
            future.addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture channelFuture) throws Exception {
                    if (channelFuture.isSuccess()) {
                        System.out.println("连接成功");
                    } else {
                        System.out.println("连接失败");

                        // 失败重连
                        bootstrap.connect("127.0.0.1", 8080).sync();

                        // 避免短时间内频繁的请求连接，可以使用定时线程池来每隔 n 秒重连一次。
                        EventLoopGroup loopGroup = bootstrap.config().group();
                        loopGroup.schedule(new Runnable() {
                            public void run() {
                                bootstrap.connect("127.0.0.1", 8080);
                            }
                        }, 5, TimeUnit.SECONDS);
                    }
                }
            });

            future.channel().closeFuture().sync();


        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            group.shutdownGracefully();
        }

    }
}
